﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WaveEngine.Framework.Services;
#endregion

namespace WaveEngine.Extensions.Resources
{
    public class ResourceManager
    {
        public static string GetResourcePath(Enum resource)
        {
            ResouceFilesAttribute atrb = GetResourceFileEnumMetaInfo(resource);
            string assetPath;
            
            if(Path.HasExtension(atrb.Path))
            {
                assetPath = atrb.Path;
            }
            else
            {
                assetPath = Path.Combine(atrb.Path, resource.ToString());
                assetPath = assetPath + "." + atrb.Formats[0];
            }
            return assetPath;
        }

        public static string GetResourceBasePath(Enum resource)
        {
            ResouceFilesAttribute atrb = GetResourceFileEnumMetaInfo(resource);
            return atrb.Path;
        }

        /// <summary>
        /// Gets the voice meta info.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="voice">The voice.</param>
        /// <returns></returns>
        internal static ResouceFilesAttribute GetResourceFileEnumMetaInfo(Enum resource)
        {
            Type assetType = resource.GetType();
            return assetType.GetCustomAttributes(true).FirstOrDefault(ca => ca is ResouceFilesAttribute) as ResouceFilesAttribute;
        }

        internal static void CheckResourceFilesExist()
        {
            var assemblies = Assembly.GetEntryAssembly().GetReferencedAssemblies().ToList();

            assemblies.Add(Assembly.GetCallingAssembly().GetName());

            List<string> failedAssets = new List<string>();
            foreach (var assemblyName in assemblies)
            {
                Assembly assembly = Assembly.Load(assemblyName);
                var assetsTypes = assembly.GetTypes()
                                          .Where(t => t.GetCustomAttributes(true)
                                                       .Any(ca => ca is ResouceFilesAttribute))
                                                       .ToList();

                foreach (var assetType in assetsTypes)
                {
                    ResouceFilesAttribute resourceAtrb = assetType.GetCustomAttributes(true)
                                                    .Single(ca => ca is ResouceFilesAttribute) as ResouceFilesAttribute;

                    string currentPath = resourceAtrb.Path;

                    string[] assetValues = Enum.GetNames(assetType);

                    foreach (string assetValue in assetValues)
                    {
                        string pathToCheck = Path.Combine(currentPath, assetValue);

                        foreach (var format in resourceAtrb.Formats)
                        {
                            if (!WaveServices.Storage.ExistsContentFile(pathToCheck + "." + format))
                            {
                                failedAssets.Add(pathToCheck + "." + format);
                            }
                        }
                    }
                }
            }

            if (failedAssets.Count > 0)
            {
                throw new IOException(string.Join("\n", failedAssets.ToArray()));
            }

        }
    }
}
